﻿using Pdf2epub.ExtractStrategy;
using Pdf2epub.Helpers;
using Pdf2epub.Interfaces;
using Pdf2epub.Model;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

namespace Pdf2epub.UI
{
    /// <summary>
    /// Interaction logic for SubblockRenderer.xaml
    /// </summary>
    public partial class SubblockRenderer
    {
        public static DependencyProperty ContentBlockProperty = DependencyProperty.Register("ContentBlock", typeof(ContentBlock), typeof(SubblockRenderer), new FrameworkPropertyMetadata(OnItemSourceChanged));
        private IProjectContext m_ProjectContext;

        public SubblockRenderer()
        {
            InitializeComponent();
        }

        public ContentBlock ContentBlock
        {
            get { return (ContentBlock)GetValue(ContentBlockProperty); }
            set { SetValue(ContentBlockProperty, value); }
        }

        private IProjectContext ProjectContext
        {
            get
            {
                if (m_ProjectContext == null)
                {
                    if (ContentBlock != null)
                    {
                        m_ProjectContext = ContentBlock.ProjectContext;
                    }
                }
                return m_ProjectContext;
            }
        }

        private static void OnItemSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var renderer = d as SubblockRenderer;
            if (renderer != null)
            {
                renderer.RenderSubblocks();
            }
        }

        private void InsertCell(ContentBlock subBlock, int column, int row)
        {
            Binding contentBinding = new Binding("Content") { Source = subBlock };

            TextBox textBox = new TextBox();
            textBox.SetBinding(TextBox.TextProperty, contentBinding);
            textBox.TextWrapping = TextWrapping.WrapWithOverflow;

            Grid.SetRow(textBox, row);
            Grid.SetColumn(textBox, column);

            grid.Children.Add(textBox);
        }

        private void InsertDummyLabel()
        {
            grid.Children.Add(new Label());
        }

        private void InsertTableColumn()
        {
            ProjectContext.Controler.InsertTableColumnIntoSubBlockCollection(ContentBlock);
            RenderSubblocks();
        }

        private void InsertTableColumnCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ContentBlock != null;
        }

        private void InsertTableRow()
        {
            ProjectContext.Controler.InsertTableRowIntoSubBlockCollection(ContentBlock);
            RenderSubblocks();
        }

        private void InsertTableRowCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ContentBlock != null;
        }

        private void OnCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command is RoutedUICommand)
            {
                RoutedUICommand uiCommand = e.Command as RoutedUICommand;
                switch (uiCommand.Name)
                {
                    case "InsertTableRow":
                        InsertTableRow();
                        break;

                    case "InsertTableColumn":
                        InsertTableColumn();
                        break;

                    case "RemoveLastRow":
                        RemoveLastRow();
                        break;

                    case "RemoveLastColumn":
                        RemoveLastColumn();
                        break;
                }
            }
        }

        private void RemoveLastColumn()
        {
            ProjectContext.Controler.RemoveLastColumnFromSubBlockCollection(ContentBlock);
            RenderSubblocks();
        }

        private void RemoveLastColumnCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (ContentBlock != null) && (ContentBlock.SubBlocks.Any());
        }

        private void RemoveLastRow()
        {
            ProjectContext.Controler.RemoveLastRowFromSubBlockCollection(ContentBlock);
            RenderSubblocks();
        }

        private void RemoveLastRowExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (ContentBlock != null) && (ContentBlock.SubBlocks.Any());
        }

        private void RenderSubblocks()
        {
            if (ContentBlock == null || ContentBlock.ContentType != ContentType.Table)
                return;

            grid.Children.Clear();

            buttonPanel.Visibility = Visibility.Visible;

            SetupGrid();

            int columnCount = TableHelper.GetColumnCount(ContentBlock);
            for (int row = 0; row < ContentBlock.SubBlocks.Count(); row++)
            {
                ContentBlock rowBlock = ContentBlock.SubBlocks.ToArray()[row];
                if (rowBlock.ContentType == ContentType.TableCaption)
                {
                    //InsertCell(rowBlock, 0, 0);
                    pnCaption.Visibility = Visibility.Visible;
                    tbHeader.SetBinding(TextBox.TextProperty, new Binding("Content") { Source = rowBlock });
                }
                else
                {
                    for (int column = 0; column < columnCount; column++)
                    {
                        if (column >= rowBlock.SubBlocks.Count)
                        {
                            InsertDummyLabel();
                        }
                        else
                        {
                            InsertCell(rowBlock.SubBlocks[column], column, row);
                        }
                    }
                }
            }
        }

        private void SetupGrid()
        {
            grid.ColumnDefinitions.Clear();
            grid.RowDefinitions.Clear();

            int columnCount = TableHelper.GetColumnCount(ContentBlock);
            int rowCount = TableHelper.GetRowCount(ContentBlock);

            for (int i = 0; i < columnCount; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition());
            }

            for (int i = 0; i < rowCount; i++)
            {
                grid.RowDefinitions.Add(new RowDefinition());
            }
        }
    }
}